package com.tansun.easycare.rule.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;

import com.tansun.easycare.rule.common.Constant;
import com.tansun.easycare.rule.datamodel.entity.RuleDataDomain;
import com.tansun.easycare.rule.ruletest.entity.RuleTest;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;

/**
 * 解析excel
 * @author xuconghui
 *
 */
public class MapSheetContentsHandler implements SheetContentsHandler{  
	
    public static final String BREAK_INFO = "excel仅读取信息头，不读取数据";
	public Map<String, MClass> metaMap;					//存储数据模型信息
	public Map<String,List<RuleDataDomain>> domainMap;	//存储domain信息
	public List<Map<String, Object>> resultMap = new ArrayList<Map<String, Object>>(); 	//存储excel数据
	public RuleTest headInfo = new RuleTest();					//存储模型信息
	public Map<String, String[]> inputField = new ConcurrentHashMap<String, String[]>();			//存储临时字段信息
	public Map<String, Object> inputMap;	//临时存储每行excel信息
	public boolean onlyhead = false;		//是否会读取信息头
    public int rowNum;						//当前行数
    
    public MapSheetContentsHandler(Map<String, MClass> metaMap, Map<String, List<RuleDataDomain>> domainMap,boolean onlyhead) {
		super();
		this.metaMap = metaMap;
		this.domainMap = domainMap;
		this.onlyhead = onlyhead;
	}

	@Override  
    public void startRow(int rowNum) {  
		inputMap = new HashMap<String, Object>();
        this.rowNum = rowNum;
    }  

    @Override  
    public void endRow(int rowNum) {
    	if(!inputMap.isEmpty()) {
    		resultMap.add(inputMap);
    	}
        if(rowNum>1 && onlyhead) {
        	throw new RuntimeException(BREAK_INFO);
        }
    }
    
    @Override  
    public void cell(String cellReference, String formattedValue, XSSFComment comment) {
    	cellReference = cellReference.replaceAll("[\\d\\.]","");
    	if(this.rowNum>3) {
    		cellWhereRowGT3(cellReference, formattedValue, comment);
    	}else if(this.rowNum == 3) {
    		cellWhereRowEQ3(cellReference, formattedValue, comment);
    	}else if(this.rowNum == 2) {
    		
    	}else if(this.rowNum == 1) {
    		
    	}else {
    		if (formattedValue.indexOf(ExcelConstant.TYPE_CELL) >= 0) {
                RuleModelTypeEnum typeEnum = RuleModelTypeEnum.getRuleModelTypeEnumByName(formattedValue.replace(ExcelConstant.TYPE_CELL, "").trim());
                if (typeEnum != null) {
                	headInfo.setModelType(typeEnum.code);
                }
            }else if (formattedValue.indexOf(ExcelConstant.MODEL_CELL) >= 0) {
            	headInfo.setRuleName(formattedValue.replace(ExcelConstant.MODEL_CELL, "").trim());
            }else if (formattedValue.indexOf(ExcelConstant.VERSION_CELL) >= 0) {
            	headInfo.setVersion(formattedValue.replace(ExcelConstant.VERSION_CELL, "").trim());
	    	}else if (formattedValue.indexOf(ExcelConstant.DATA_CELL) >= 0) {
	            headInfo.setId(formattedValue.replace(ExcelConstant.DATA_CELL, "").trim());
	    	}
    	}
    	
    }  
    public void cellWhereRowEQ3(String cellReference, String formattedValue, XSSFComment comment) {
    	if(StringUtils.isNotEmpty(formattedValue)) {
	    	p:for(String className:metaMap.keySet()) {
	    		MClass mclass = metaMap.get(className);
				Map<String,MField> fieldMap = mclass.getFieldMap();
				for(String name:fieldMap.keySet()) {
					MField mField = fieldMap.get(name);
					String dmpkey = mclass.getChzn()+"."+mField.getChzn();
					if(formattedValue.equals(dmpkey)) {
						String[] classField = new String[] {className,name,mField.getType(),mField.getDomainStr(),mField.getDomain()};
						inputField.put(cellReference, classField);
						break p;
					}
				}
	    	}
    	}
    }
    
    @SuppressWarnings("unchecked")
	public void cellWhereRowGT3(String cellReference, String formattedValue, XSSFComment comment) {
    	if(inputField.containsKey(cellReference)&&StringUtils.isNotEmpty(formattedValue)) {
        	String[] classField = inputField.get(cellReference);
        	String className = classField[0];
        	String paramName = classField[1];
        	String type = classField[2];
        	String domainStr = classField[3];
        	String domain = classField[4];
        	Map<String, Object> supinputMap = null;
        	if(inputMap.containsKey(className)) {
        		supinputMap = (Map<String, Object>) inputMap.get(className);
        	}else {
        		supinputMap = new HashMap<String, Object>();
        		inputMap.put(className, supinputMap);
        	}
        	if(type.equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_LONG)) {
        		supinputMap.put(paramName, Math.round((Double.parseDouble(formattedValue))));
        	}else if(StringUtils.isNotBlank(domainStr)) {
        		List<RuleDataDomain> domainList = domainMap.get(domain);
                for (RuleDataDomain item : domainList) {
                    if (item.getName().equals(formattedValue)) {
                        supinputMap.put(paramName, item.getDomainValue());
                        break;
                    }
                }
        	}else {
        		supinputMap.put(paramName, formattedValue);
        	}
    	}
    }
    @Override  
    public void headerFooter(String text, boolean isHeader, String tagName) {  
          
    }
    
    public List<Map<String, Object>> getResults(){
    	return resultMap;
    }

	public RuleTest getHeadInfo() {
		return headInfo;
	}
    
}  